package com.example.mysql.学习笔记.高级.数据库的优化之索引.索引优化与查询优化;

public class 关联查询优化 {
}
/**
 * 关联查询优化
 * 内连接 查询优化器可以决定 驱动表和被驱动表的
 *           驱动表数据少   被驱动表 数据多    即小表驱动大表
 *       如果只有一个索引  被驱动表是带索引的
 *
 * 外连接
 *
 *
 * JOIN语句原理
 * join方式连接多个表，本质就是各个表之间数据的循环匹配。
 * MySQL5.5 版本之前，MySQL只支持-种表间关联方式，就是嵌套循环(Nested Loop Join)。
 * 如果关联表的数据量很大，则join关联的执行时间会非常长。
 * 在MySQL5.5以后的版本中，MySQL通过引入 BNLJ 算法来优化嵌套执行。
 *
 * 1.驱动表和被驱动表
 *  驱动表就是主表，被驱动表就是从表、非驱动表。
 *
 * 2. Simple Nested-Loop Join (简单嵌套循环连接)  SNLJ
 * 算法相当简单，从表A中取出一条数据1,遍历表B,将匹配到的数据放到result..以此类推,
 * 驱动表A中的每-条记录与被驱动表B的记录进行判断:
 * 可以看到这种方式效率是非常低的，以上述表A数据100条，表8数据1000条计算，则A"B= 10万次。
 *
 * 3. Index Nested-Loop Join (索引嵌套循环连接)   INLJ
 * Index Nested-Loop Join其优化的思路主要是为了减少内层表数据的匹配次数，
 * 所以要求被驱动表上必须有索引才行。
 * 通过外层表匹配条件直接与内层表索引|进行匹配，避免和内层表的每条记录去进行比较，
 * 这样极大的减少了对内层表的匹配次数。

 *
 * 4. Block Nested-Loop Join (块嵌套循环连接) BNLJ
 * 简单来说   就是加载第一次的时候  会用缓存把数据缓存起来，第二次匹配的时候 ，会使用缓存
 *
 * 不再是逐条获取驱动表的数据，而是一块一块的获取， 引入了join buffer缓冲区 ，
 * 将驱动表join相关的部分数据列(大小受join buffer的限制)缓存到join buffr中，
 * 然后全表打描被驱动表，被驱动表的每一条记录--次性和join buffer中的所有驱动表记录进行匹配(内存中操作)，
 * 将简单嵌套循环中的多次比较合并成-次,降低了被驱动表的访问频率。
 *
 *
 * 开销统计如下:
 * 开销统计          SNLJ         INLJ        BNLJ
 * 外表扫描次数:       1           1            1
 * 内表扫描次数:       A           0            A*  批量缓存/总数+1
 * 读取记录数:        A+B"A       A+B           A+B*A*批量缓存/总数
 * JOIN比较次数:      B*A         A*索引高度     B*A
 * 回表读取记录次数:    0           B             0
 *
 * 5. Join小结
 * 1、整体效率比较:
 *     INLJ> BNLJ> SNLJ
 * 2、永远用小结果集驱动大结果集(其本质就是减少外层循环的数据数量)
 *     (小的度 量单位指的是表行数*每行大小)
 * 3、为被驱动表匹配的条件增加索弓|(减少内层表的循环匹配次数)
 * 4、增大join buffer size的大小(- -次缓存的数据越多, 那么内层包的扫表次数就越少)|
 * 5、减少驱动表不必要的字段查询(字段越少, join buffer所缓存的数据就越多)
 *
 * 6. Hash Join
 * **从MySQL的8.0.20版本开始将废弃BNLJ,
 * 因为从MySQL8.0.18版本开始就加入了hash join默认都会使用hash join
 * ●Nested Loop:
 * 对于被连接的数据子集较小的情况，Nested Loop是个较好的选择。
 * ●Hash Join是做大数据集连接时的常用方式，优化器使用两个表中较小(相对较小)的表利用
 * Join Key在内存中建立散列表，然后扫描较大的表并探测散列表,找出与Hash表匹配的行。
 * 。这种方式适用于较小的表完全可以放于内存中的情况，这样总成本就是访问两个表的成本之和。
 * 。在表很大的情况下并不能完全放入内存，这时优化器会将它分割成若干不同的分区，不能放入内存的部分
 * 就把该分区写入磁盘的临时段，此时要求有较大的临时段从而尽量提高I/O的性能。
 * 。它能够很好的工作于没有索引的大表和并行查询的环境中，并提供最好的性能。大多数人都说它是Join的
 * 重型升降机。Hash Join只能应用于等值连接(如WHERE A.COL1 = B.COL2),这是由Hash的特点决定的。
 *
 *
 */